package com.aizhixin.lab.project.course.service;

import cn.hutool.core.date.DateUtil;
import com.aizhixin.lab.account.dto.AccountDTO;
import com.aizhixin.lab.common.core.ApiReturnConstants;
import com.aizhixin.lab.common.core.DataValidity;
import com.aizhixin.lab.common.dto.SortDTO;
import com.aizhixin.lab.common.utils.PageJdbcUtil;
import com.aizhixin.lab.company.domain.AccountDomain;
import com.aizhixin.lab.company.service.UserService;
import com.aizhixin.lab.project.course.domain.*;
import com.aizhixin.lab.project.course.entity.ProjectClass;
import com.aizhixin.lab.project.course.entity.ProjectClassStu;
import com.aizhixin.lab.project.course.entity.ProjectGroup;
import com.aizhixin.lab.project.course.entity.ProjectGroupType;
import com.aizhixin.lab.project.course.repository.ProjectClassRepository;
import com.aizhixin.lab.project.course.repository.ProjectClassStuRepository;
import com.aizhixin.lab.project.course.repository.ProjectGroupRepository;
import com.aizhixin.lab.project.course.repository.ProjectGroupTypeRepository;
import com.aizhixin.lab.project.course.uilt.DoubleUtil;
import com.aizhixin.lab.project.course.vo.GroupInfoVo;
import com.aizhixin.lab.task.domain.ReleaseTaskDomain;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class ProjectGroupService {
    @Autowired
    private PageJdbcUtil pageJdbcUtil;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProjectGroupRepository projectGroupRepository;
    @Autowired
    private ProjectClassStuRepository projectClassStuRepository;
    @Autowired
    private ProjectClassRepository classRepository;
    @Autowired
    private ProjectClassStuRepository stuRepository;
    @Autowired
    private ProjectGroupTypeRepository projectGroupTypeRepository;

    public Map<String, Object> releaseNotice(NoticeDomain domain) {
        Map<String, Object> result = new HashMap<>();
        ProjectGroup projectGroup = projectGroupRepository.findOne(domain.getGroupId());
        if (Objects.isNull(projectGroup)) {
            result.put(ApiReturnConstants.SUCCESS, false);
            result.put(ApiReturnConstants.ERROR, "未查询该小组");
        } else {
            projectGroup.setNotice(domain.getNotice());
            projectGroupRepository.save(projectGroup);
            result.put(ApiReturnConstants.SUCCESS, true);
            result.put(ApiReturnConstants.ERROR, "发布成功");
        }
        return result;
    }

    public void stuRandomGroup(StuRandomDomain domain) {
        List<ProjectClass> projectClassList = classRepository.findByProjectId(domain.getProjectId());
        List<String> classIds = projectClassList.stream().map(ProjectClass::getId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
        Integer count = stuRepository.countByProjectIdAndDeleteFlagAndProjectClassIdIn(domain.getProjectId(), 0, classIds);
        if (domain.getType() == 1) {
            if (count != null) {
                List<ProjectClassStu> projectClassStuList = stuRepository.findAllByProjectIdAndDeleteFlagAndProjectClassIdInAndGroupIdIsNull(domain.getProjectId(), 0, classIds);
                Integer groupNum = count % domain.getGroupNum() == 0 ? count / domain.getGroupNum() : count / domain.getGroupNum() + 1;
                List<ProjectGroup> projectGroupList = new ArrayList<>();
                for (int a = 0; a < groupNum; a++) {
                    ProjectGroup projectGroup = new ProjectGroup();
                    projectGroup.setId(UUID.randomUUID().toString());
                    projectGroup.setProjectId(domain.getProjectId());
                    projectGroup.setGroupNum(0);
                    projectGroup.setDeleteFlag(0);
                    projectGroup.setLikeNum(0);
                    projectGroup.setUrgeNum(0);
                    projectGroup.setMaxNum(domain.getGroupNum());
                    projectGroup.setCreatedDate(new Date());
                    projectGroup.setGroupName("小组" + new Date().getTime());
                    projectGroupList.add(projectGroup);
                }
                for (int a = 0; a < projectClassStuList.size(); a++) {
                    projectClassStuList.get(a).setGroupId(projectGroupList.get(a % groupNum).getId());
                }
                stuRepository.save(projectClassStuList);
                projectGroupRepository.save(projectGroupList);
            }
        } else if (domain.getType() == 2) {
            for (String str : classIds) {
                List<ProjectClassStu> projectClassStuList = stuRepository.findAllByProjectIdAndDeleteFlagAndProjectClassIdAndGroupIdIsNull(domain.getProjectId(), 0, str);
                if (projectClassStuList != null && projectClassStuList.size() > 0) {
                    Integer groupNum = projectClassStuList.size() % domain.getGroupNum() == 0 ? projectClassStuList.size() / domain.getGroupNum() : projectClassStuList.size() / domain.getGroupNum() + 1;
                    List<ProjectGroup> projectGroupList = new ArrayList<>();
                    for (int a = 0; a < groupNum; a++) {
                        ProjectGroup projectGroup = new ProjectGroup();
                        projectGroup.setId(UUID.randomUUID().toString());
                        projectGroup.setProjectId(domain.getProjectId());
                        projectGroup.setGroupNum(0);
                        projectGroup.setDeleteFlag(0);
                        projectGroup.setLikeNum(0);
                        projectGroup.setUrgeNum(0);
                        projectGroup.setMaxNum(domain.getGroupNum());
                        projectGroup.setCreatedDate(new Date());
                        projectGroup.setGroupName("小组" + new Date().getTime());
                        projectGroupList.add(projectGroup);
                    }
                    for (int a = 0; a < projectClassStuList.size(); a++) {
                        projectClassStuList.get(a).setGroupId(projectGroupList.get(a % groupNum).getId());
                    }
                    stuRepository.save(projectClassStuList);
                    projectGroupRepository.save(projectGroupList);
//                    for (int a = 0; a < groupNum; a++) {
//                        List<ProjectClassStu> stuList = stuRepository.findAllByProjectIdAndDeleteFlagAndProjectClassIdAndGroupIdIsNull(domain.getProjectId(), 0, str);
//                        if (stuList.size() > 0) {
//                            ProjectGroup projectGroup = new ProjectGroup();
//                            projectGroup.setId(UUID.randomUUID().toString());
//                            projectGroup.setProjectId(domain.getProjectId());
//                            projectGroup.setGroupNum(groupNum);
//                            projectGroup.setDeleteFlag(0);
//                            projectGroup.setLikeNum(0);
//                            projectGroup.setUrgeNum(0);
//                            projectGroup.setMaxNum(domain.getGroupNum());
//                            projectGroup.setCreatedDate(new Date());
//                            projectGroup.setGroupName("小组" + new Date().getTime());
//                            ProjectGroup group = projectGroupRepository.save(projectGroup);
//                            for (int k = 0; k < stuList.size(); k++) {
//                                stuList.get(k).setGroupId(group.getId());
//                                stuRepository.save(stuList.get(k));
//                                if (k == domain.getGroupNum() - 1) {
//                                    break;
//                                }
//                            }
//                        }
//                    }
                }
            }
        }
        updateGroupNum(domain.getProjectId());
    }

    public void updateGroupNum(String projectId) {
        List<ProjectGroup> byProjectId = projectGroupRepository.findByProjectId(projectId);
        List<ProjectGroup> collect = byProjectId.stream().map(group -> {
            group.setGroupNum(stuRepository.countByGroupIdAndDeleteFlag(group.getId(), DataValidity.VALID.getState()));
            if (group.getGroupNum()==0){
                group.setDeleteFlag(DataValidity.INVALID.getState());
            }
            return group;
        }).collect(Collectors.toList());
        projectGroupRepository.save(collect);

    }

    public int findProjectNum(String projectId) {
        return stuRepository.countByProjectIdAndDeleteFlag(projectId, 0);
    }

    public String projectIdFindGroupId(String projectId, Long stuId) {
        ProjectClassStu projectClassStu = projectClassStuRepository.findByProjectIdAndStuIdAndDeleteFlag(projectId, stuId, 0);
        return projectClassStu.getGroupId();
    }

    public Map<String, Object> findGroupOtherProjectId(String groupId) {
        Map<String, Object> result = new HashMap<>();
        String string = pageJdbcUtil.getString("SELECT c.project_id FROM c_project_class c LEFT JOIN c_project p ON c.project_id=p.id WHERE c.group_id='" + groupId + "' AND p.project_type='备选项目' AND c.delete_flag=0 AND p.delete_flag=0");
        String string1 = pageJdbcUtil.getString("SELECT c.project_id FROM c_project_class c LEFT JOIN c_project p ON c.project_id=p.id WHERE c.group_id='" + groupId + "' AND p.project_type='练习项目' AND c.delete_flag=0 AND p.delete_flag=0");
        result.put(ApiReturnConstants.SUCCESS, true);
        result.put("bftProject", string);
        result.put("testProject", string1);
        return result;
    }


    public ProjectGroup stuCreationGroup(StuCreationGroupDomain domain, Long stuId) {
        ProjectGroup projectGroup = new ProjectGroup();
        projectGroup.setId(UUID.randomUUID().toString());
        projectGroup.setProjectId(domain.getProjectId());
        projectGroup.setGroupNum(domain.getGroupNum());
        projectGroup.setGroupName(domain.getGroupName());
        projectGroup.setCreatedDate(new Date());
        projectGroup.setMaxNum(domain.getMaxNum());
        projectGroup.setDeleteFlag(0);
        projectGroup.setUrgeNum(0);
        projectGroup.setLikeNum(0);
        projectGroup.setNotice(domain.getNotice());
        ProjectClassStu projectClassStu = projectClassStuRepository.findByProjectIdAndStuIdAndDeleteFlag(domain.getProjectId(), stuId, 0);
        projectClassStu.setGroupId(projectGroup.getId());
        projectClassStu.setRole("leader");
        projectClassStuRepository.save(projectClassStu);
        return projectGroupRepository.save(projectGroup);
    }

    public void applyGroupLeader(ApplyGroupLeaderDomain domain) {
        ProjectGroup group = projectGroupRepository.findOne(domain.getGroupId());
        group.setNotice(domain.getNotice());
        group.setGroupName(domain.getGroupName());
        projectGroupRepository.save(group);
        ProjectClassStu classStu = projectClassStuRepository.findByProjectIdAndStuIdAndGroupIdAndDeleteFlag(domain.getProjectId(), domain.getStuId(), domain.getGroupId(), 0);
        ProjectClassStu roleStu = projectClassStuRepository.findByProjectIdAndRoleAndGroupIdAndDeleteFlag(domain.getProjectId(), "leader", domain.getGroupId(), 0);
        if (roleStu == null) {
            classStu.setRole("leader");
            projectClassStuRepository.save(classStu);
        } else {
            roleStu.setRole("member");
            classStu.setRole("leader");
            projectClassStuRepository.save(roleStu);
            projectClassStuRepository.save(classStu);
        }
    }

    RowMapper<GroupInfoVo> groupInfoVoRowMapper = new RowMapper<GroupInfoVo>() {

        @Override
        public GroupInfoVo mapRow(ResultSet rs, int rowNum) throws SQLException {

            GroupInfoVo domain = new GroupInfoVo();
            domain.setId(rs.getString("id"));
            domain.setGroupName(rs.getString("group_name"));
            domain.setLeaderName(rs.getString("leader_name"));
            domain.setMemberName(rs.getString("member_name"));
            domain.setMaxNum(rs.getInt("max_num"));

            return domain;
        }
    };

    /**
     * 查看项目下小组列表
     *
     * @param projectId
     * @return
     */
    public List<GroupInfoVo> findProjectGroupInfo(String projectId) {
        String sql = "SELECT cp.id,cp.group_name,cp.max_num,(SELECT GROUP_CONCAT(tu.`name`) FROM c_project_class_stu cpc LEFT JOIN t_user tu ON cpc.stu_id=tu.id WHERE cp.id=cpc.group_id AND cpc.role='leader') leader_name,(SELECT GROUP_CONCAT(tu.`name`) FROM c_project_class_stu cpc LEFT JOIN t_user tu ON cpc.stu_id=tu.id WHERE cp.id=cpc.group_id AND cpc.role='member') member_name FROM c_project_group cp WHERE cp.project_id='" + projectId + "' and cp.delete_flag=0";
        List<GroupInfoVo> info = pageJdbcUtil.getInfo(sql, groupInfoVoRowMapper);
        info.forEach(item -> {
            try {
                String string = pageJdbcUtil.getString("SELECT c.project_id FROM c_project_class c LEFT JOIN c_project p ON c.project_id=p.id WHERE c.group_id='" + item.getId() + "' AND p.project_type='备选项目' AND c.delete_flag=0 AND p.delete_flag=0");
                item.setBftProjectId(string);
            } catch (EmptyResultDataAccessException e) {
            }
            try {
                String string1 = pageJdbcUtil.getString("SELECT c.project_id FROM c_project_class c LEFT JOIN c_project p ON c.project_id=p.id WHERE c.group_id='" + item.getId() + "' AND p.project_type='练习项目' AND c.delete_flag=0 AND p.delete_flag=0");
                item.setTestProjectId(string1);
            } catch (EmptyResultDataAccessException e) {

            }
        });
        return info;
    }

    public Map<String, Object> stuAddGroup(StuAddGroupDomain domain) {
        Map<String, Object> map = new HashMap<>();
        ProjectGroup projectGroup = projectGroupRepository.findOne(domain.getGroupId());
        Integer stuCount = projectClassStuRepository.countByProjectIdAndGroupIdAndDeleteFlag(domain.getProjectId(), domain.getGroupId(), 0);
        if (stuCount < projectGroup.getMaxNum()) {
            ProjectClassStu stu = projectClassStuRepository.findByProjectIdAndStuIdAndDeleteFlag(domain.getProjectId(), domain.getStuId(), 0);
            stu.setGroupId(domain.getGroupId());
            stu.setRole(domain.getRole_id());
            projectClassStuRepository.save(stu);
            projectGroup.setGroupNum(stuCount + 1);
            projectGroupRepository.save(projectGroup);
            map.put(ApiReturnConstants.SUCCESS, true);
            map.put(ApiReturnConstants.DATA, "加入成功");
            return map;
        }
        map.put(ApiReturnConstants.SUCCESS, false);
        map.put(ApiReturnConstants.DATA, "人数已超过小组最大成员数！");
        return map;
    }

    public String stuDeleteGroup(StuAddGroupDomain domain) {
        ProjectGroup projectGroup = projectGroupRepository.findOne(domain.getGroupId());
        ProjectClassStu stu = projectClassStuRepository.findByProjectIdAndStuIdAndDeleteFlag(domain.getProjectId(), domain.getStuId(), 0);
        stu.setGroupId(null);
        stu.setRole("member");
        projectClassStuRepository.save(stu);
        Integer stuCount = projectClassStuRepository.countByProjectIdAndGroupIdAndDeleteFlag(domain.getProjectId(), domain.getGroupId(), 0);
        projectGroup.setGroupNum(stuCount);
        projectGroupRepository.save(projectGroup);
        return "踢人成功！";
    }

    public void saveGroupSetting(ProjectGroupTypeDomain domain) {
        ProjectGroupType projectGroupType = projectGroupTypeRepository.findByProjectIdAndDeleteFlag(domain.getProjectId(), DataValidity.VALID.getState());
        if (Objects.isNull(projectGroupType)) {
            projectGroupType = new ProjectGroupType();
            projectGroupType.setId(UUID.randomUUID().toString());
        }
        projectGroupType.setProjectId(domain.getProjectId());
        projectGroupType.setCreatedDate(new Date());
        projectGroupType.setDeleteFlag(0);
        projectGroupType.setMaxNum(domain.getMaxNum());
        projectGroupType.setMinNum(domain.getMaxNum());
        projectGroupType.setType(domain.getType());
        if (domain.getType() == 1) {
            projectGroupType.setEndTime(DateUtil.parse(domain.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        projectGroupTypeRepository.save(projectGroupType);
    }

    public void updateRole(ProjectGroupStuRoleTypeDomain domain) {
        ProjectClassStu classStu = projectClassStuRepository.findByProjectIdAndStuIdAndDeleteFlag(domain.getProjectId(), domain.getStu_id(), 0);
        classStu.setRoleId(domain.getRole_id());
        projectClassStuRepository.save(classStu);
    }

    public List<ProjectClassStu> findGroupMember(findGroupMemberDomain domain) {
        return projectClassStuRepository.findByProjectIdAndGroupIdAndDeleteFlag(domain.getProjectId(), domain.getGroupId(), 0);
    }

    public Map<String, Object> findGroupType(String projectId, Long stuId) {
        Map<String, Object> map = new HashMap<>();
        ProjectGroupType one = projectGroupTypeRepository.findByProjectIdAndDeleteFlag(projectId, DataValidity.VALID.getState());
        ProjectClassStu projectClassStu = projectClassStuRepository.findByProjectIdAndStuIdAndDeleteFlag(projectId, stuId, 0);
        if (Objects.isNull(one)) {
            map.put("type", 0);
        } else {
            map.put("type", one.getType());
        }
        if (Objects.isNull(projectClassStu)) {
            map.put("role", null);
        } else {
            map.put("role", projectClassStu.getRole());
        }
        return map;
    }

    /**
     * 小组点赞
     *
     * @param groupId 小组ID
     * @param type
     * @return
     */
    public Map<String, Object> likeOrUrge(String groupId, Integer type) {
        Map<String, Object> result = new HashMap<>();
        ProjectGroup projectGroup = projectGroupRepository.findOne(groupId);
        Integer num = 0;
        if (Objects.isNull(projectGroup)) {
            result.put(ApiReturnConstants.SUCCESS, false);
            result.put(ApiReturnConstants.ERROR, "未查询该小组");
            return result;
        }
        if (type == 10) {
            projectGroup.setLikeNum(projectGroup.getLikeNum() + 1);
            num = projectGroup.getLikeNum();
        } else {
            projectGroup.setUrgeNum(projectGroup.getUrgeNum() + 1);
            num = projectGroup.getUrgeNum();
        }
        projectGroupRepository.save(projectGroup);
        result.put(ApiReturnConstants.SUCCESS, true);
        result.put(ApiReturnConstants.DATA, num);
        return result;

    }

    public Map<String, Object> deleteGroup(String groupId) {
        Map<String, Object> result = new HashMap<>();
        for (String s : groupId.split(",")) {
            ProjectGroup projectGroup = projectGroupRepository.findOne(s);
            if (Objects.isNull(projectGroup)) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "未查询该小组");
                return result;
            }
            projectGroup.setDeleteFlag(DataValidity.INVALID.getState());
            projectGroupRepository.save(projectGroup);
            List<ProjectClassStu> stuList = projectClassStuRepository.findByGroupIdAndDeleteFlag(s, DataValidity.VALID.getState());
            if (stuList.size() > 0) {
                stuList.forEach(stu -> {
                    stu.setGroupId(null);
                    stu.setRole("");
                });
                projectClassStuRepository.save(stuList);
            }
        }
        result.put(ApiReturnConstants.SUCCESS, true);
        return result;

    }
}
